package com.hanhai.material.config.security;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hanhai.material.common.result.Result;
import com.hanhai.material.common.result.ResultTool;
import com.hanhai.material.wages.entity.FinUserRoster;
import com.hanhai.material.wxauth.entity.SysMenu;
import com.hanhai.material.wages.entity.SysRole;
import com.hanhai.material.wages.entity.SysUser;
import com.hanhai.material.wages.service.*;
import com.hanhai.material.utils.jwt.JWTUtil;
import com.hanhai.material.utils.redis.RedisUtil;
import com.hanhai.material.wxauth.entity.SysRoleMenu;
import com.hanhai.material.wxauth.service.SysMenuService;
import com.hanhai.material.wxauth.service.SysRoleMenuService;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.*;

import static com.hanhai.material.wages.entity.table.FinUserRosterTableDef.FIN_USER_ROSTER;
import static com.hanhai.material.wxauth.entity.table.SysMenuTableDef.SYS_MENU;
import static com.hanhai.material.wxauth.entity.table.SysRoleMenuTableDef.SYS_ROLE_MENU;

/**
 * @author youchuang
 * @description:登录成功处理
 **/
@Component
@Log4j2
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    JWTUtil jwtUtil;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    SysUserService sysUserService;

    @Autowired
    SysUserRoleService sysUserRoleService;

    @Autowired
    SysRoleService sysRoleService;


    @Autowired
    SysMenuService sysMenuService;

    @Autowired
    SysRoleMenuService sysRoleMenuService;
    @Autowired
    FinUserRosterService finUserRosterService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = response.getOutputStream();
        String username = authentication.getName();
        // 生成jwt，并放置到请求头中
        String token = JWTUtil.sign(username, jwtUtil.getSecret());
        response.setHeader(jwtUtil.getHeader(), token);
        /*将token存入Redis*/
//        this.redisUtil.hset(username, "token", token, 3 * 10 * 60);
        this.redisUtil.hset(username, "token", token);

        SysUser sysUser = this.sysUserService.getByUsername(username);
        QueryWrapper queryWrapper1=QueryWrapper.create();
        queryWrapper1.where(FIN_USER_ROSTER.USER_ID.eq(sysUser.getUnionid()));
        LocalDate now=LocalDate.now();
        queryWrapper1.where(FIN_USER_ROSTER.ARCHIVES_DATE.between(now.minusDays(2),now));
        queryWrapper1.limit(1);
        FinUserRoster finUserRoster=this.finUserRosterService.getOne(queryWrapper1);
        sysUser.setUserInfo(finUserRoster);
        String roleId = sysUser.getRoleId();
        SysRole sysRole=this.sysRoleService.getById(roleId);
        sysUser.setRole(sysRole);
        boolean isSuper = sysUser.getRole().getRoleLevel() == 1;
        List<SysMenu> sysMenuList = new ArrayList<>();
        if (isSuper) {
            QueryWrapper queryWrapper=QueryWrapper.create();
            queryWrapper.where(SYS_MENU.PARENT_ID.eq("0")).orderBy(SYS_MENU.MENU_ORDER,true);
            sysMenuList = this.sysMenuService.getMapper().selectListWithRelationsByQuery(queryWrapper);
        }
        else {
            QueryWrapper queryWrapper=QueryWrapper.create();
            queryWrapper.where(SYS_ROLE_MENU.ROLE_ID.eq(roleId));
            List<SysRoleMenu> sysRoleMenuList = this.sysRoleMenuService.list(queryWrapper);
            for (SysRoleMenu sysRoleMenu : sysRoleMenuList) {
                SysMenu sysMenu = this.sysMenuService.getById(sysRoleMenu.getMenuId());
                if (sysMenu != null) {
                    if (sysMenu.getParentId().equals("self")) {
                        queryWrapper=QueryWrapper.create();
                        queryWrapper.where(SYS_MENU.PARENT_ID.eq(sysMenu.getId())).orderBy(SYS_MENU.MENU_ORDER,true).where(SYS_MENU.IS_DELETE.eq(false));
                        List<SysMenu> menuList = this.sysMenuService.list(queryWrapper);
                        sysMenu.setMenuList(menuList);
                        sysMenuList.add(sysMenu);
                    }
                }
            }

        }
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(sysUser);
        jsonObject.remove("password");
        Map<String, Object> map = new HashMap<>();
        map.put("userInfo", jsonObject);
//        map.put("functions", JSONArray.toJSON(sysFuncList));
        map.put("menus", JSONArray.toJSON(sysMenuList));
        map.put("token", token);
        map.put("message", "登录成功");
        String ip = this.getIpAddress(request);
        sysUser.setIp(ip);
        sysUser.setLastLoginTime(new Date());
        this.sysUserService.updateById(sysUser);
        log.error("IP:" + ip);

        Result<?> result = ResultTool.success(map);
        outputStream.write(JSONUtil.toJsonStr(result).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }

    /**
     * 获取真实ip地址,不返回内网地址
     *
     * @param request
     * @return
     */
    private String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
            if (ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
            if (ip.equals("127.0.0.1")) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                ip = inet.getHostAddress();
            }
        }

        if (request.getHeader("X-Real-IP") != null && !"".equals(request.getHeader("X-Real-IP")) && !"unknown".equalsIgnoreCase(request.getHeader("X-Real-IP"))) {
            ip = request.getHeader("X-Real-IP");
        }

        if (request.getHeader("Proxy-Client-IP") != null && !"".equals(request.getHeader("Proxy-Client-IP")) && !"unknown".equalsIgnoreCase(request.getHeader("Proxy-Client-IP"))) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (request.getHeader("WL-Proxy-Client-IP") != null && !"".equals(request.getHeader("WL-Proxy-Client-IP")) && !"unknown".equalsIgnoreCase(request.getHeader("WL-Proxy-Client-IP"))) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        log.info("用户ip：" + ip);
        return ip;
    }


}
